﻿#region Using

using System;
using System.Xml;
using System.IO;
using System.Linq;
using System.Configuration;
using System.Globalization;
using System.Collections.Generic;
using System.Collections.Specialized;
using BlogEngine.Core;
using BlogEngine.Core.Providers;
using newtelligence.DasBlog.Runtime;

#endregion

namespace BlogEngine.dasblog
{
	/// <summary>
	/// A storage provider for BlogEngine that uses dasBlog XML files.
	/// </summary>
	public partial class dasBlogProvider : XmlBlogProvider
	{
		internal IBlogDataService bds;

		/// <summary>
		/// Retrieves a post based on the specified Id.
		/// </summary>
		public override Post SelectPost(Guid id)
		{
			Entry e = bds.GetEntry(id.ToString());
			Post post = new Post();
			post.Title = e.Title;
			if (e.Description == null)
				post.Description = "";
			else
				post.Description = e.Description;
			post.Content = e.Content;
			post.DateCreated = e.CreatedLocalTime;
			post.DateModified = e.ModifiedLocalTime;
			post.Author = e.Author;
			post.IsPublished = e.IsPublic;
			post.IsCommentsEnabled = e.AllowComments;
			post.Slug = e.Title.Replace(" ", "");

			// Tags
			string[] cats = e.Categories.Split(';');
			foreach(string cat in cats)
				post.Tags.Add(cat);

			CommentCollection cc = bds.GetPublicCommentsFor(e.EntryId);
			// comments			
			foreach (newtelligence.DasBlog.Runtime.Comment c in cc)
			{
				BlogEngine.Core.Comment comment = new BlogEngine.Core.Comment();
				comment.Id = new Guid(c.EntryId);
				comment.ParentId = Guid.Empty;
				comment.Author = c.Author;
				comment.Email = c.AuthorEmail;
				comment.Parent = post;
				comment.Country = string.Empty;
				comment.IP = c.AuthorIPAddress;

				if (c.AuthorHomepage.Length != 0)
				{
					Uri website;
					if (Uri.TryCreate(c.AuthorHomepage, UriKind.Absolute, out website))
						comment.Website = website;
				}

				comment.IsApproved = c.SpamState == SpamState.NotSpam || c.SpamState == SpamState.NotChecked;
				comment.Content = c.Content;
				comment.DateCreated = c.CreatedLocalTime;
				post.Comments.Add(comment);
			}

			post.Comments.Sort();

			return post;
		}

		/// <summary>
		/// Inserts a new Post to the data store.
		/// </summary>
		/// <param name="post"></param>
		public override void InsertPost(Post post)
		{
			Entry e = new Entry();
			if (post.IsChanged || post.IsNew)
			{
				e.Author = post.Author;
				e.Title = post.Title;
				e.Description = post.Description;
				e.Content = post.Content;
				e.IsPublic = post.IsPublished;
				e.AllowComments = post.IsCommentsEnabled;
				e.CreatedLocalTime = post.DateCreated;
				e.ModifiedLocalTime = post.DateModified;
				e.EntryId = post.Id.ToString();
				foreach (string t in post.Tags)
				{
					if (e.Categories == null)
						e.Categories = t;
					e.Categories = e.Categories + ";" + t;
				}
				bds.SaveEntry(e, null);
			}
			else
				e = bds.GetEntry(post.Id.ToString());

			CommentCollection comments = bds.GetPublicCommentsFor(post.Id.ToString());
			// Remove any deleted comments
			if(post.Comments.Count < comments.Count)
				foreach (newtelligence.DasBlog.Runtime.Comment comment in bds.GetPublicCommentsFor(post.Id.ToString()))
				{
					var query = from a in post.Comments
											where a.Id.ToString().Equals(comment.EntryId)
											select a as BlogEngine.Core.Comment;
					if (query.Count<BlogEngine.Core.Comment>() == 0)
						bds.DeleteComment(post.Id.ToString(), comment.EntryId);
				}

			// Add new comments
			if (post.Comments.Count > comments.Count)
				foreach(BlogEngine.Core.Comment comment in post.Comments)
				{
					if (bds.GetCommentById(e.EntryId, comment.Id.ToString()) != null) continue;
					newtelligence.DasBlog.Runtime.Comment cmt = new newtelligence.DasBlog.Runtime.Comment();
					cmt.IsPublic = comment.IsPublished;
					if (comment.IsApproved)
						cmt.SpamState = SpamState.NotSpam;
					cmt.TargetEntryId = post.Id.ToString();
					cmt.EntryId = Guid.NewGuid().ToString();
					cmt.TargetTitle = e.Title;
					cmt.Author = comment.Author;
					cmt.AuthorEmail = comment.Email;
					cmt.AuthorHomepage = comment.Website.ToString();
					cmt.AuthorIPAddress = comment.IP;
					cmt.CreatedLocalTime = comment.DateCreated;
					cmt.Content = comment.Content;
					bds.AddComment(cmt, null);
				}
		}

		/// <summary>
		/// Updates a Post.
		/// </summary>
		public override void UpdatePost(Post post)
		{
			InsertPost(post);
		}

		/// <summary>
		/// Deletes a post from the data store.
		/// </summary>
		public override void DeletePost(Post post)
		{
			bds.DeleteEntry(post.Id.ToString(), null);
		}

		/// <summary>
		/// Retrieves all posts from the data store
		/// </summary>
		/// <returns>List of Posts</returns>
		public override List<Post> FillPosts()
		{
			bds = BlogDataServiceFactory.GetService(ConfigurationManager.AppSettings["dasBlogContentDir"], null);
			EntryCollection col = bds.GetEntries(null, null, Int32.MaxValue, Int32.MaxValue);
			List<Post> posts = new List<Post>();
			foreach (Entry e in col)
			{
				Post post = Post.Load(new Guid(e.EntryId));
				posts.Add(post);
			}
			posts.Sort();
			return posts;
		}
	}
}